<template>
  <view class="load-more-container">
    <!-- 加载状态 -->
    <view v-if="loading" class="loading">
      <uni-icons type="spinner-cycle" size="24" color="#888" class="loading-icon"></uni-icons>
      <text class="loading-text">{{ loadingText }}</text>
    </view>

    <!-- 加载完成 -->
    <view v-else-if="finished" class="finished">{{ finishedText }}</view>

    <!-- 加载失败 -->
    <view v-else-if="error" class="error" @click="handleRetry">
      <uni-icons type="error" size="24" color="#f56c6c"></uni-icons>
      <text class="error-text">{{ errorText }}</text>
    </view>

    <!-- 触发加载的锚点 -->
    <view ref="observerElement" class="observer"></view>
  </view>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, defineProps, defineEmits } from 'vue';

// 定义props
const props = defineProps({
  // 是否加载中
  loading: {
    type: Boolean,
    default: false
  },
  // 是否加载完成
  finished: {
    type: Boolean,
    default: false
  },
  // 是否加载失败
  error: {
    type: Boolean,
    default: false
  },
  // 加载中文字
  loadingText: {
    type: String,
    default: '加载中...'
  },
  // 加载完成文字
  finishedText: {
    type: String,
    default: '没有更多数据了'
  },
  // 加载失败文字
  errorText: {
    type: String,
    default: '加载失败，点击重试'
  },
  // 触发加载的阈值(px)
  threshold: {
    type: Number,
    default: 100
  }
});

// 定义事件
const emit = defineEmits<{
  (e: 'loadMore'): void;
  (e: 'retry'): void;
}>();

// 观察者对象和锚点元素
const observer = ref<UniApp.IntersectionObserver | null>(null);
const observerElement = ref<HTMLElement | null>(null);

// 重试处理
const handleRetry = () => {
  emit('retry');
};

// 创建交叉观察器
const createObserver = () => {
  if (!observerElement.value) return;

  // 使用uni-app的API创建交叉观察器，确保多平台兼容性
  observer.value = uni.createIntersectionObserver()
    .relativeToViewport({ bottom: props.threshold })
    .observe(observerElement.value, (res) => {
      // 当元素可见且不处于加载中、未完成、无错误状态时触发加载更多
      if (res.intersectionRatio > 0 && !props.loading && !props.finished && !props.error) {
        emit('loadMore');
      }
    });
};

// 生命周期钩子
onMounted(() => {
  createObserver();
});

onUnmounted(() => {
  // 销毁观察器
  observer.value?.disconnect();
});
</script>

<style scoped lang="scss">
.load-more-container {
  width: 100%;
  padding: 20rpx 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.loading {
  display: flex;
  align-items: center;
  color: #888;
  font-size: 28rpx;

  .loading-icon {
    margin-right: 10rpx;
    animation: spin 1s linear infinite;
  }
}

.finished {
  color: #888;
  font-size: 28rpx;
}

.error {
  display: flex;
  align-items: center;
  color: #f56c6c;
  font-size: 28rpx;
  cursor: pointer;

  .error-icon {
    margin-right: 10rpx;
  }
}

.observer {
  width: 100%;
  height: 1px;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>